home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Incognito / cdev / ChooserDialog.cp < prev    next >
Encoding:
Text File  |  1994-02-09  |  17.1 KB  |  842 lines  |  [TEXT/MPS ]

  1. #ifndef __DIALOGS__
  2. #include <Dialogs.h>
  3. #endif
  4.  
  5. #ifndef __APPLETALK__
  6. #include <AppleTalk.h>
  7. #endif
  8.  
  9. #ifndef __DIALOGUTIL__
  10. #include <DialogUtil.h>
  11. #endif
  12.  
  13. #ifndef __QUICKDRAW__
  14. #include <Quickdraw.h>
  15. #endif
  16.  
  17. #ifndef __EXCEPTIONS__
  18. #include <Exceptions.h>
  19. #endif
  20.  
  21. #ifndef __EVENTS__
  22. #include <Events.h>
  23. #endif
  24.  
  25. #ifndef __PLSTRINGFUNCS__
  26. #include <PLStringFuncs.h>
  27. #endif
  28.  
  29. #ifndef __CHOOSERDIALOG__
  30. #include "ChooserDialog.h"
  31. #endif
  32.  
  33. #pragma segment Main
  34.  
  35. CChooserDialog::CChooserDialog()
  36. {
  37.     MPPParamBlock p;
  38.     short err;
  39.  
  40.     p.MPPioCompletion = 0L;
  41.     p.SETSELF.newSelfFlag = 1;
  42.     PSetSelfSend(&p, false);
  43.     ResetLastKey(0);
  44. }
  45.  
  46. #pragma segment Main
  47. void CChooserDialog::InitZoneList()
  48. {
  49.     DoBuildZoneList();
  50.     if (!fZoneList->GetHeight())
  51.     {
  52.         fZoneList->InsertItem("\p*");
  53.         fZoneList->SelectItem("\p*");
  54.     } else HiliteUserZone();
  55. }
  56.  
  57.  
  58. #pragma segment Main
  59. void CChooserDialog::InitDeviceList()
  60. {
  61.     Str32    theZone;
  62.     
  63.     fBuffer[0] = 1;
  64.     fBuffer[1] = '=';
  65.     fBuffer[2] = 1;
  66.     fBuffer[3] = '=';
  67.  
  68.     PLstrcpy((StringPtr) &fBuffer[4], fZoneList->GetCurrentSelection(theZone) ? theZone : "\p*");    
  69.  
  70.     if (!fLookupBuffer)
  71.     {
  72.         fLookupBuffer = NewPtr(253*sizeof(EntityName));
  73.         if (!fLookupBuffer) return;
  74.     }
  75.     
  76.     if (fLookupParam.MPP.ioResult == 1)        // kill outstanding requests, if any
  77.     {
  78.         fLookupParam.NBPKILL.nKillQEl = (Ptr) &fLookupParam.MPP.qLink;
  79.         PKillNBP(&fLookupParam, false);
  80.     }
  81.  
  82.     fLookupParam.NBP.interval = 5;
  83.     fLookupParam.NBP.count = 4;
  84.     fLookupParam.NBP.NBPPtrs.entityPtr = (Ptr) fBuffer;
  85.     fLookupParam.NBP.parm.Lookup.retBuffPtr = fLookupBuffer;
  86.     fLookupParam.NBP.parm.Lookup.retBuffSize = GetPtrSize(fLookupBuffer);
  87.     fLookupParam.NBP.parm.Lookup.maxToGet = GetPtrSize(fLookupBuffer)/sizeof(EntityName);
  88.     PLookupName(&fLookupParam, true);
  89. }
  90.  
  91. #pragma segment Main
  92. void CChooserDialog::ChangeActive(short theItem)
  93. {
  94.     CListManager    *theList;
  95.     
  96.     EraseBigFrame(fTheDialog, GetActive());
  97.     switch (GetActive())
  98.     {
  99.         case kZoneList:
  100.             theList = fZoneList;
  101.             break;
  102.         case kChosenList:
  103.             theList = fChosenList;
  104.             break;
  105.         case kDeviceList:
  106.             theList = fDeviceList;
  107.             break;
  108.     }
  109.     theList->Deactivate();
  110.     fActiveItem = theItem;
  111.     switch (GetActive())
  112.     {
  113.         case kZoneList:
  114.             theList = fZoneList;
  115.             break;
  116.         case kChosenList:
  117.             theList = fChosenList;
  118.             break;
  119.         case kDeviceList:
  120.             theList = fDeviceList;
  121.             break;
  122.     }
  123.     theList->Activate();
  124.     DrawBigFrame(fTheDialog, GetActive());
  125. }
  126.  
  127.  
  128.  
  129. #pragma segment Main
  130. CChooserDialog::~CChooserDialog()
  131. {
  132.     delete fChosenList;
  133.     delete fDeviceList;
  134.     delete fZoneList;
  135.     if (fLookupParam.MPP.ioResult == 1)        // kill outstanding requests, if any
  136.     {
  137.         fLookupParam.NBPKILL.nKillQEl = (Ptr) &fLookupParam.MPP.qLink;
  138.         PKillNBP(&fLookupParam, false);
  139.     }
  140.     if (fLookupBuffer) DisposePtr(fLookupBuffer);
  141.     DisposeDialog(fTheDialog);
  142. }
  143.  
  144.  
  145. #pragma segment Main
  146.  
  147.  
  148.  
  149. #pragma segment Main
  150. void CChooserDialog::Run()
  151. {
  152.     short    itemHit;
  153.     GrafPtr    oldPort;
  154.     ModalFilterUPP    theFilter;
  155.     
  156.     theFilter = NewModalFilterProc(EventFilterProc);
  157.     GetPort(&oldPort);
  158.     SetPort(fTheDialog);
  159.     hiliteItem(fTheDialog, kAddButton, 255);
  160.     hiliteItem(fTheDialog, kRemoveButton, 255);
  161.     
  162.     do
  163.     {
  164.         ModalDialog(theFilter, &itemHit);
  165.         switch (itemHit)
  166.         {
  167.             case kAddButton:
  168.                 DoAddButton();
  169.                 break;
  170.             case kRemoveButton:
  171.                 DoRemoveButton();
  172.                 break;
  173.         case kZoneList:
  174.         case kChosenList:
  175.         case kDeviceList:
  176.             if (itemHit - GetActive())
  177.             {
  178.                 ChangeActive(itemHit);
  179.             }
  180.             switch (itemHit)
  181.             {
  182.                 case kZoneList:
  183.                     DoZoneHit();
  184.                     break;
  185.                 case kChosenList:
  186.                     DoChosenHit();
  187.                     break;
  188.                 case kDeviceList:
  189.                     DoDeviceHit();
  190.                     break;
  191.             }
  192.             default:
  193.                 break;
  194.         }
  195.         AdjustButtons();
  196.     } while (itemHit != kDoneButton);
  197.     
  198.     DisposeRoutineDescriptor(theFilter);
  199.     SetPort(oldPort);
  200. }
  201.  
  202. #pragma segment Main
  203. void CChooserDialog::SetChosenList(CListManager *originalList)
  204. {
  205.     Cell    theCell = {0,0};
  206.     short    height = originalList->GetHeight();
  207.     Str32    theItem;
  208.     
  209.     fOriginalList = originalList;
  210.     if (fOriginalList->GetFirstItem(theItem, theCell))
  211.     {
  212.         fChosenList->InsertItem(theItem);
  213.         while (fOriginalList->GetNextItem(theItem, theCell))
  214.         {
  215.             fChosenList->InsertItem(theItem);
  216.         }
  217.     }
  218. }
  219.  
  220. #pragma segment Main
  221. short CChooserDialog::DoTabCycle(short theDirection)
  222. {
  223.     short    newActive;
  224.     
  225.     switch (GetActive())
  226.     {
  227.         case kZoneList:
  228.             newActive = !theDirection ? kDeviceList : kChosenList;
  229.             break;
  230.         case kDeviceList:
  231.             newActive = !theDirection ? kChosenList : kZoneList;
  232.             break;
  233.         case kChosenList:
  234.             newActive = !theDirection ? kZoneList : kDeviceList;
  235.             break;
  236.     }
  237.     ChangeActive(newActive);
  238.     return GetActive();    
  239. }
  240.  
  241. #pragma segment Main
  242. void CChooserDialog::Initialize(short resID)
  243. {
  244.     DialogPtr    theDialog;
  245.     CListManager    *theList;
  246.     
  247.     theDialog = GetNewDialog(resID, nil, (WindowPtr) -1);
  248.     require(theDialog, getnewdialog);
  249.     SetWRefCon(theDialog, (long) this);
  250.     
  251.     theList = new CListManager(kChosenList, theDialog);
  252.     require(theList, chosenlist);
  253.     fChosenList = theList;
  254.     theList->Deactivate();
  255.     
  256.     theList = new CListManager(kZoneList, theDialog);
  257.     require(theList, zonelist);
  258.     theList->Deactivate();
  259.     fZoneList = theList;
  260.     InitZoneList();
  261.     
  262.     theList = new CListManager(kDeviceList, theDialog, 2);
  263.     require(theList, devicelist);
  264.     theList->Activate();
  265.     fDeviceList = theList;
  266.     InitDeviceList();
  267.     
  268.     fActiveItem = kDeviceList;
  269.     DrawBigFrame(theDialog, kDeviceList);
  270.     DrawSmallFrame(theDialog, kChosenList);
  271.     DrawSmallFrame(theDialog, kDeviceList);
  272.     DrawSmallFrame(theDialog, kZoneList);
  273.  
  274.     fTheDialog = theDialog;
  275.     return;
  276.  
  277. devicelist:
  278.     delete fZoneList;
  279. zonelist:
  280.     delete fChosenList;
  281. chosenlist:
  282.     delete theDialog;
  283. getnewdialog:
  284.     return;
  285. }
  286.  
  287. #pragma segment Main
  288. void CChooserDialog::DoUpdate(EventRecord *theEvent)
  289. {
  290.     if (theEvent->message == (long) fTheDialog)
  291.     {
  292.         DrawBigFrame(fTheDialog, GetActive());
  293.         DrawSmallFrame(fTheDialog, kZoneList);
  294.         DrawSmallFrame(fTheDialog, kDeviceList);
  295.         DrawSmallFrame(fTheDialog, kChosenList);
  296.         fZoneList->Update();
  297.         fChosenList->Update();
  298.         fDeviceList->Update();
  299.     }
  300.     else
  301.     {
  302.         BeginUpdate((WindowPtr) theEvent->message);
  303.         EndUpdate((WindowPtr) theEvent->message);
  304.     }
  305. }
  306.  
  307.  
  308. #pragma segment Main
  309. void CChooserDialog::DoNull(void)
  310. {
  311.     EntityName    theEntity;
  312.     AddrBlock    theAddress;
  313.  
  314.     if (fLookupParam.MPP.ioResult >= noErr && fLookupParam.NBP.parm.Lookup.numGotten > 0)
  315.     {
  316.         while (fNumGotten < fLookupParam.NBP.parm.Lookup.numGotten)
  317.         {
  318.             fNumGotten += 1;
  319.             if (!NBPExtract(fLookupBuffer, fLookupParam.NBP.parm.Lookup.numGotten, fNumGotten, &theEntity, &theAddress))
  320.             {
  321.                 Cell    theCell;
  322.                 
  323.                 if (!fDeviceList->InsertItem(theEntity.objStr))
  324.                 {
  325.                     if (fDeviceList->FindItem(theEntity.objStr, theCell))
  326.                     {
  327.                         fDeviceList->AddItem(theEntity.objStr, theCell);
  328.                     }
  329.                 }
  330.                 else fDeviceList->FindItem(theEntity.objStr, theCell);
  331.                 theCell.h+=1;
  332.                 fDeviceList->SetItem(theEntity.typeStr, theCell);
  333.             }
  334.         }
  335.     }
  336. }
  337.  
  338.  
  339. #pragma segment Main
  340. void CChooserDialog::DoKey(EventRecord *theEvent)
  341. {
  342.     char            key = (char)(theEvent->message & charCodeMask);
  343.     CListManager    *theList;
  344.     Cell            theCell;
  345.     Str32            theItem;
  346.     
  347.     switch (GetActive())
  348.     {
  349.         case kZoneList:
  350.             theList = fZoneList;
  351.             break;
  352.         case kChosenList:
  353.             theList = fChosenList;
  354.             break;
  355.         case kDeviceList:
  356.             theList = fDeviceList;
  357.             break;
  358.     }
  359.     switch (key)
  360.     {
  361.         case 0x08:
  362.             DoRemoveButton();
  363.             ResetLastKey(theEvent->when);
  364.             AdjustButtons();
  365.             break;
  366.         case 0x09:
  367.             DoTabCycle(theEvent->modifiers  & shiftKey);
  368.             ResetLastKey(theEvent->when);
  369.             AdjustButtons();
  370.             break;
  371.         case 0x1c:        // left
  372.             if (theList->IsSelection(theCell))
  373.             {
  374.                 theCell.h-=1;
  375.                 if (theCell.h < 0) break;
  376.                 theList->DeselectList();
  377.                 theList->SelectItem(theCell);
  378.             }
  379.             else
  380.             {
  381.                 theCell.h = 0;
  382.                 theCell.v = 0;
  383.                 theList->SelectItem(theCell);
  384.             }
  385.             AdjustButtons();
  386.             theList->AutoScroll();
  387.             ResetLastKey(theEvent->when);
  388.             break;
  389.         case 0x1d:        // right
  390.             if (theList->IsSelection(theCell))
  391.             {
  392.                 theCell.h +=1;
  393.                 if (theCell.h < theList->GetWidth())
  394.                 {
  395.                     theList->DeselectList();
  396.                     theList->SelectItem(theCell);
  397.                 }
  398.             }
  399.             else
  400.             {
  401.                 theCell.h = theList->GetWidth()-1;
  402.                 theCell.h < 0 ? 0 : theCell.h;
  403.                 theCell.v = 0;
  404.                 theList->SelectItem(theCell);
  405.             }
  406.             AdjustButtons();
  407.             theList->AutoScroll();
  408.             ResetLastKey(theEvent->when);
  409.             break;
  410.         case 0x1e:        // up arrow
  411.             if (theList->IsSelection(theCell))
  412.             {
  413.                 theCell.v-=1;
  414.                 if (theCell.v < 0) break;
  415.                 theList->DeselectList();
  416.                 theList->SelectItem(theCell);
  417.             }
  418.             else
  419.             {
  420.                 theCell.h = 0;
  421.                 theCell.v = theList->GetHeight() - 1;
  422.                 theList->SelectItem(theCell);
  423.             }
  424.             AdjustButtons();
  425.             theList->AutoScroll();
  426.             ResetLastKey(theEvent->when);
  427.             break;
  428.         case 0x1f:        // down arrow
  429.             if (theList->IsSelection(theCell))
  430.             {
  431.                 theCell.v+= 1;
  432.                 if (theCell.v < theList->GetHeight())
  433.                 {
  434.                     theList->DeselectList();
  435.                     theList->SelectItem(theCell);
  436.                 }
  437.             }
  438.             else
  439.             {
  440.                 theCell.h = theCell.v = 0;
  441.                 theList->SelectItem(theCell);
  442.             }
  443.             theList->AutoScroll();
  444.             AdjustButtons();
  445.             ResetLastKey(theEvent->when);
  446.             break;
  447.         default:
  448.             DoTyping(theEvent, key);
  449.             break;
  450.     }
  451. }
  452.  
  453.  
  454. #pragma segment Main
  455. void CChooserDialog::AdjustButtons(void)
  456. {
  457.     Str32    theItem;
  458.     Cell    theCell;
  459.     
  460.     switch (GetActive())
  461.     {
  462.         case kZoneList:
  463.             hiliteItem(fTheDialog, kRemoveButton, 255);
  464.             hiliteItem(fTheDialog, kAddButton, 255);
  465.             break;
  466.         case kChosenList:
  467.             hiliteItem(fTheDialog, kRemoveButton, fChosenList->IsSelection() ? 0 : 255);
  468.             hiliteItem(fTheDialog, kAddButton, 255);
  469.             break;
  470.         case kDeviceList:
  471.             hiliteItem(fTheDialog, kRemoveButton, 255);
  472.             if (fDeviceList->IsSelection(theCell))
  473.             {
  474.                 fDeviceList->GetItem(theItem, theCell);
  475.                 hiliteItem(fTheDialog, kAddButton, fChosenList->IsItemPresent(theItem) ? 255 : 0);
  476.             }
  477.             else
  478.             {
  479.                 hiliteItem(fTheDialog, kAddButton, 255);
  480.             }
  481.             break;
  482.     }
  483. }
  484.  
  485.  
  486. #pragma segment Main
  487. void CChooserDialog::DoZoneHit()
  488. {
  489.     Cell    theOldCell, theNewCell;
  490.     
  491.     if (fZoneList->IsSelection(theOldCell))
  492.     {
  493.         fZoneList->Click(fTheEvent.where, fTheEvent.modifiers);
  494.         fZoneList->IsSelection(theNewCell);
  495.         if ((theOldCell.h == theNewCell.h) && (theOldCell.v == theNewCell.v));
  496.         else
  497.         {
  498.             fDeviceList->Empty();
  499.             fNumGotten = 0;
  500.             InitDeviceList();
  501.         }
  502.     }
  503.     else
  504.     {
  505.         fZoneList->Click(fTheEvent.where, fTheEvent.modifiers);
  506.         if (fZoneList->IsSelection())
  507.         {
  508.             fDeviceList->Empty();
  509.             fNumGotten = 0;
  510.             InitDeviceList();
  511.         }
  512.     }
  513.     AdjustButtons();    
  514. }
  515.  
  516.  
  517. #pragma segment Main
  518. void CChooserDialog::DoChosenHit()
  519. {
  520.     fChosenList->Click(fTheEvent.where, fTheEvent.modifiers);
  521.     AdjustButtons();
  522. }
  523.  
  524.  
  525. #pragma segment Main
  526. void CChooserDialog::DoDeviceHit()
  527. {
  528.     Str32    theItem;
  529.     
  530.     if (fDeviceList->Click(fTheEvent.where, fTheEvent.modifiers))    // if dbl–click
  531.     {
  532.         DoAddButton();
  533.     }
  534.     AdjustButtons();
  535. }
  536.  
  537. #pragma segment Main
  538. void CChooserDialog::DoTyping(EventRecord *theEvent, char key)
  539. {
  540.     Cell            theCell;
  541.     long            when = theEvent->when;
  542.     CListManager    *theList;
  543.  
  544.     if (key < ' ') return;
  545.     if ((when - fLastCharTime) > 30)
  546.     {
  547.         ResetLastKey(when);
  548.     }
  549.     fLastCharTime = when;
  550.     fCharString[++(fCharString[0])] = key;
  551.     switch (GetActive())
  552.     {
  553.         case kZoneList:
  554.             theList = fZoneList;
  555.             break;
  556.         case kDeviceList:
  557.             theList = fDeviceList;
  558.             break;
  559.         case kChosenList:
  560.             theList = fChosenList;
  561.             break;
  562.         default:
  563.             break;
  564.     }
  565.     theList->DeselectList();
  566.     theList->BinarySearchInsensitive(fCharString, theCell);
  567.     theList->SelectItem(theCell);
  568.     AdjustButtons();
  569. }
  570.  
  571.  
  572. #pragma segment Main
  573. void CChooserDialog::ResetLastKey(long when)
  574. {
  575.     fCharString[0] = 0;
  576.     fLastCharTime = when;
  577. }
  578.  
  579. #pragma segment Main
  580. OSErr CChooserDialog::DoBuildZoneList(void)
  581. {
  582.     ATPParamBlock atppb;
  583.     char zones[kZonesSize], * zptr, data[255];
  584.     OSErr err;
  585.  
  586.     BDSElement dBDS;                                            // the BDS for GetZoneList call 
  587.     short index, count, i;
  588.     short ignore;
  589.     short nodeNetAddress, bridgeNode;
  590.  
  591.     dBDS.buffSize = kZonesSize;                                    // set up BDS 
  592.     dBDS.buffPtr = zones;
  593.  
  594.     atppb.ATPatpFlags = 0;
  595.  
  596.     // Get network address of node & node ID of bridge (if any). 
  597.  
  598.     err = GetNodeAddress(&ignore, &nodeNetAddress);
  599.     if (err) return (err);
  600.  
  601.     if (!(bridgeNode = GetBridgeAddress())) return (noErr);
  602.     // We have added all zero zones to the ist, so we are done. 
  603.  
  604.     atppb.ATPaddrBlock.aNet = nodeNetAddress;
  605.     atppb.ATPaddrBlock.aNode = bridgeNode;                        // Get node of bridge. 
  606.     atppb.ATPaddrBlock.aSocket = kZIPSocket;                    // The socket we want. 
  607.     atppb.ATPreqLength = 0;
  608.     atppb.ATPreqPointer = nil;
  609.     atppb.ATPbdsPointer = (Ptr) & dBDS;
  610.     atppb.ATPnumOfBuffs = 1;
  611.     atppb.ATPtimeOutVal = kATPTimeOutVal;
  612.     atppb.ATPretryCount = kATPRetryCount;
  613.  
  614.     index = 1;
  615.     count = 0;
  616.  
  617.     do
  618.     {
  619.         atppb.ATPuserData = kGetZoneListCall + index;            // Indicate GetZoneList request. 
  620.         err = PSendRequest(&atppb, false);                        // Send sync request. 
  621.         if (err) return (err);
  622.  
  623.         count += dBDS.userBytes & kZoneCount;                    // find out how many returned 
  624.         zptr = zones;                                            // put current pointer at start 
  625.         do
  626.         {                                                        // get each zone 
  627.             for (i = zptr[0]; i; --i) data[i - 1] = zptr[i];
  628.             fZoneList->InsertItem((Str32) zptr);
  629.             zptr += (*zptr + 1);                                // bump up current pointer
  630.             ++index;                                            // increment which zone
  631.         } while (index <= count);
  632.  
  633.     } while ((dBDS.userBytes & kMoreZones) == 0);                //     keep going until none left
  634.  
  635.     return (noErr);
  636. }
  637.  
  638.  
  639. #pragma segment Main
  640. OSErr CChooserDialog::HiliteUserZone(void)
  641. {
  642.     Str32 zone;
  643.     short zoneLen, i;
  644.     OSErr err;
  645.  
  646.     if (!(err = OldStyleGetMyZone(zone)))
  647.     {
  648.         for (zoneLen = zone[i = 0]; i < zoneLen; ++i) zone[i] = zone[i + 1];
  649.         fZoneList->SelectItem(zone);
  650.     }
  651.     return (err);
  652. }
  653.  
  654.  
  655. #pragma segment Main
  656. OSErr CChooserDialog::OldStyleGetMyZone(StringPtr str)
  657. {
  658.     ATPParamBlock atppb;
  659.     OSErr err;
  660.  
  661.     BDSElement dBDS;                                        // the BDS for GetZoneList call
  662.     short ignore;
  663.     short nodeNetAddress, bridgeNode;
  664.  
  665.     dBDS.buffSize = sizeof(Str32);
  666.     dBDS.buffPtr = (Ptr)str;
  667.  
  668.     atppb.ATPatpFlags = 0;
  669.  
  670.     // Get network address of node & node ID of bridge (if any).
  671.  
  672.     err = GetNodeAddress(&ignore, &nodeNetAddress);
  673.     if (err) return (err);
  674.  
  675.     if (!(bridgeNode = GetBridgeAddress())) return (noErr); // We have added all zero
  676.                                                             // zones to the ist, so we are done.
  677.  
  678.     atppb.ATPaddrBlock.aNet = nodeNetAddress;
  679.     atppb.ATPaddrBlock.aNode = bridgeNode;                    // Get node of bridge.
  680.     atppb.ATPaddrBlock.aSocket = kZIPSocket;                // The socket we want. 
  681.     atppb.ATPreqLength = 0;
  682.     atppb.ATPreqPointer = nil;
  683.     atppb.ATPbdsPointer = (Ptr) & dBDS;
  684.     atppb.ATPnumOfBuffs = 1;
  685.     atppb.ATPtimeOutVal = kATPTimeOutVal;
  686.     atppb.ATPretryCount = kATPRetryCount;
  687.  
  688.     atppb.ATPuserData = kGetMyZoneCall;                        // Indicate GetMyZone request.
  689.     return (PSendRequest(&atppb, false));                    // Send sync request
  690. }
  691.  
  692. #pragma segment Main
  693. pascal Boolean CChooserDialog::EventFilterProc(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
  694. {
  695.     GrafPtr    oldPort;
  696.     CChooserDialog    *myDialog = (CChooserDialog *)GetWRefCon(theDialog);
  697.     
  698.     GetPort(&oldPort);
  699.     SetPort(theDialog);
  700.     
  701.     switch (theEvent->what)
  702.     {
  703.         case nullEvent:
  704.             myDialog->DoNull();
  705.             break;
  706.         case keyDown:
  707.         case autoKey:
  708.             if (theEvent->modifiers & cmdKey)
  709.             {
  710.                 switch (theEvent->message & charCodeMask)
  711.                 {
  712.                     case 'a':
  713.                     case 'A':
  714.                         myDialog->DoAddButton();
  715.                         break;
  716.                     case 'd':
  717.                     case 'D':
  718.                         *itemHit = kDoneButton;
  719.                         SetPort(oldPort);
  720.                         return true;
  721.                         break;
  722.                     case 'R':
  723.                     case 'r':
  724.                         myDialog->DoRemoveButton();
  725.                         break;
  726.                 }
  727.             } else myDialog->DoKey(theEvent);
  728.             break;
  729.         case updateEvt:
  730.             myDialog->DoUpdate(theEvent);
  731.             break;
  732.         case mouseDown:
  733.             myDialog->fTheEvent = *theEvent;
  734.             break;
  735.         default:
  736.             break;
  737.     }
  738.     SetPort(oldPort);
  739.     return false;
  740. }
  741.  
  742. #pragma segment Main
  743. void CChooserDialog::DoAddButton(void)
  744. {
  745.     Str32    theItem;
  746.     Cell    theCell;
  747.     
  748.     if (getValue(fTheDialog, kAddButton) == 0)
  749.     if (GetActive() == kDeviceList)
  750.     while (fDeviceList->IsSelection(theCell))        // get the selected device
  751.     {
  752.         fDeviceList->GetItem(theItem, theCell);
  753.         if (fChosenList->InsertItem(theItem))        // insert it into the current list
  754.         {
  755.             fOriginalList->InsertItem(theItem);        // and in the one passed in.
  756.         }
  757.         fDeviceList->DeselectItem(theCell);
  758.     }
  759.     AdjustButtons();
  760. }
  761.  
  762.  
  763. #pragma segment Main
  764. void CChooserDialog::DoRemoveButton(void)
  765. {
  766.     Str32    theItem;
  767.     Cell    theCell;
  768.     
  769.     if (getValue(fTheDialog, kRemoveButton) == 0)
  770.     if (GetActive() == kChosenList)
  771.     {
  772.         while (fChosenList->IsSelection(theCell))
  773.         {
  774.             fChosenList->GetItem(theItem, theCell);
  775.             fOriginalList->RemoveItem(theItem);
  776.             fChosenList->RemoveItem(theItem);
  777.         }
  778.         AdjustButtons();
  779.     }
  780. }
  781.  
  782.  
  783.  
  784. void EraseBigFrame(DialogPtr theDialog, short item)
  785. {
  786.     Rect box;
  787.     GrafPtr oldPort;
  788.     PenState theState;
  789.     RGBColor theBackColor, theForeColor;
  790.  
  791.     GetPort(&oldPort);
  792.     SetPort(theDialog);
  793.     GetPenState(&theState);
  794.     PenNormal();
  795.     PenSize(2, 2);
  796.     GetBackColor(&theBackColor);
  797.     GetForeColor(&theForeColor);
  798.     RGBForeColor(&theBackColor);
  799.     getBox(theDialog, item, &box);
  800.     InsetRect(&box, -4, -4);
  801.     FrameRect(&box);
  802.     SetPenState(&theState);
  803.     RGBForeColor(&theForeColor);
  804.     SetPort(oldPort);
  805. }
  806.  
  807. void DrawSmallFrame(DialogPtr theDialog, short item)
  808. {
  809.     Rect box;
  810.     GrafPtr oldPort;
  811.     PenState theState;
  812.  
  813.     GetPort(&oldPort);
  814.     SetPort(theDialog);
  815.     GetPenState(&theState);
  816.     PenNormal();
  817.     getBox(theDialog, item, &box);
  818.     InsetRect(&box, -1, -1);
  819.     FrameRect(&box);
  820.     SetPenState(&theState);
  821.     SetPort(oldPort);
  822. }
  823.  
  824. void DrawBigFrame(DialogPtr theDialog, short item)
  825. {
  826.     Rect box;
  827.     GrafPtr oldPort;
  828.     PenState theState;
  829.  
  830.     GetPort(&oldPort);
  831.     SetPort(theDialog);
  832.     GetPenState(&theState);
  833.     PenNormal();
  834.     PenSize(2, 2);
  835.     getBox(theDialog, item, &box);
  836.     InsetRect(&box, -4, -4);
  837.     FrameRect(&box);
  838.     SetPenState(&theState);
  839.     SetPort(oldPort);
  840. }
  841.  
  842.